﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Linq;
using System.Text;
using Net.Chirash.Twitter.TwitterClient;
using Net.Chirash.Twitter.TwitterDatabase;

namespace Net.Chirash.Twitter.TweetZone.WindowComponents.ViewModels
{
    public class TimelineContainerViewModel : Net.Chirash.Twitter.TweetZone.WindowComponents.ViewModels.PagableContainerViewModel<Status>
    {
        public TimelineContainerViewModel()
            : this(TimelineTypes.Home)
        { }

        public TimelineContainerViewModel(TimelineTypes types)
            : this(types, App.CurrentApp.User)
        { }

        public TimelineContainerViewModel(TimelineTypes types, User currentUser)
            : base()
        {
            this.TimelineType = types;
            this.CurrentUser = currentUser;
            this.IsDBOnly = true;
        }

        #region Public Properties

        #region public TimelineTypes TimelineType { get; set; }
        private TimelineTypes _TimelineType;
        public TimelineTypes TimelineType
        {
            get { return _TimelineType; }
            set { _TimelineType = value; OnPropertyChanged("TimelineType"); }
        }
        #endregion
        #region public bool IsDBOnly { get; set; }
        private bool _IsDBOnly;
        public bool IsDBOnly
        {
            get { return _IsDBOnly; }
            set
            {
                _IsDBOnly = value;

                if (value == true) // isDBonly true
                {
                    this.TwitterCommand = TwitterCommandFactory.CreateLocalTwitterCommand();
                }
                else // not DB only
                {
                    this.TwitterCommand = TwitterCommandFactory.CreateRemoteTwitterCommand();
                }
                OnPropertyChanged("IsDBOnly");
            }
        }
        #endregion

        public override string ContainerTitle
        {
            get
            {
                var ret = Enum.GetName(typeof(TimelineTypes), this.TimelineType);
                if (CurrentUser != null)
                    ret += string.Format(" of @{0}", CurrentUser.ScreenName);
                return ret;
            }
        }

        public override void TaskSubscribe()
        {
            this.ReceiveDeletedInfo();

            base.TaskSubscribe();
        }

        #endregion

        #region private Events

        private static void IsDBOnly_PropertyChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            var inst = sender as TimelineContainerViewModel;

            if ((bool)e.NewValue == true) // isDBonly true
            {
                inst.TwitterCommand = TwitterCommandFactory.CreateLocalTwitterCommand();
            }
            else // not DB only
            {
                inst.TwitterCommand = TwitterCommandFactory.CreateRemoteTwitterCommand();
            }
        }

        #endregion

        #region Protected Members

        protected class TimelineRefreshArgs
            : PagingEventArgs<Status>
        {
            public TimelineTypes type;
        }

        protected override IEnumerable<Status> UpdateDatabaseDataProviding(ITwitterCommand command)
        {
            RefreshArgs<Status> args = null;
            try
            {
                this.InvokeByComposerIfNeeded(() =>
                {
                    args = CreateRefreshArgs(args);
                });
            }
            catch (InvalidOperationException) { throw new InvalidOperationException("Dispatcher消失の関係でRefreshArgsを作成することができません"); }

            var option = new TimelineOption()
            {
                UserID = args.CurrentUser.UserID,
                SinceID = (!object.ReferenceEquals(args.TopData, null)) ? args.TopData.UserID + 1L : 0L,
                Count = args.RequiredCount,
                MaxID = long.MaxValue,
            };

            return TwitterDataFactory.GetTimeline(option, (args as TimelineRefreshArgs).type, command);
        }

        protected override void UpdateDatabase(TwitterCaching caching, IEnumerable<Status> updatelist)
        {
            caching.UpdateStatuses(updatelist);
        }

        protected override RefreshArgs<Status> CreateRefreshArgs(RefreshArgs<Status> args)
        {
            TimelineRefreshArgs result = args as TimelineRefreshArgs;
            if (args == null)
                result = new TimelineRefreshArgs();

            base.CreateRefreshArgs(result);

            result.type = this.TimelineType;

            return result;
        }

        protected override void RefreshDataProviding(RefreshArgs<Status> e)
        {
            var args = e as TimelineRefreshArgs;
            var topdata = args.TopData as Status;
            var option = new TimelineOption()
            {
                Count = args.RequiredCount,
                MaxID = long.MaxValue,
                UserID = args.CurrentUser.UserID,
            };

            //if (e.TopData != null) //差分読み込み
            //{
            //    option.SinceID = topdata.ID + 1;
            //}
            //else
            //{
            option.SinceID = 0;
            //}

            var timeline = TwitterDataFactory.GetTimeline(option, args.type, args.TwitterCommand);
            args.ResultEnumerable = timeline;
        }

        protected override void PagingDataProviding(PagingEventArgs<Status> e)
        {
            var args = e as TimelineRefreshArgs;
            var lastdata = e.LastData as Status;
            var option = new TimelineOption()
            {
                Count = e.RequiredCount,
                MaxID = lastdata.StatusID - 1,
                SinceID = 0,
                UserID = args.CurrentUser.UserID
            };

            var timeline = TwitterDataFactory.GetTimeline(option, args.type, args.TwitterCommand);
            e.ResultEnumerable = timeline;
        }

        #endregion
    }

}
